#ifndef PLAYER_H
#define PLAYER_H

//Weapon class prototypes
class Inventory_Gun;
class Inventory_Arty;
class Inventory_Melee;
class Inventory_Equip;

class Player
{
 public: 
  int Player_Number;
  char* Player_Name;
  int Class_Type;
  float X_Position,     Y_Position;
  float X_Velocity,     Y_Velocity;
  float X_Acceleration, Y_Acceleration;
  float Velocity_Cap, Acceleration_Cap;
  float Angle, Hit_Radius; 
  int Health, Level, Experience;
  Inventory_Gun*   Cur_Gun;
  Inventory_Arty*  Cur_Arty;
  Inventory_Melee* Cur_Melee;
  Inventory_Equip* Cur_Equip;
  int Primary_Ammo, Secondary_Ammo, Equipment_Ammo;
  //WeaponPack*  Primary_Weapon, Secondary_Weapon, Equipment;
  float Damage_Modifier, ROF_Modifier, Speed_Modifier, Accuracy_Modifier;
  float Initial_Delay_Modifier, Recoil_Modifer, Fire_Activation_Time;
  float Evasion_Modifier, Push_Back_Modifier, Explosion_Radius_Modifier;
  float Scope_Range_Modifier;
  hgeSprite*    Player_Sprite_Layer1; //Head Gear
  hgeSprite*    Player_Sprite_Layer2; //Arms Armor
  hgeSprite*    Player_Sprite_Layer3; //Body Armor
  hgeAnimation* Player_Sprite_Layer4; //Foot Steps
 
  //Graphical
  Player(hgeSprite* Layer1, hgeSprite* Layer2, hgeSprite* Layer3, hgeAnimation* Layer4);
  void Render_Player();
  void UpdatePosition(float X, float Y);
  void UpdateVelocity(float X, float Y);
  void UpdateAcceleration(float X, float Y);
  void ApplyAcceleration(float X, float Y);
  void DampAcceleration(float ScaleA, float ScaleV, float Stop_threshold);
  void ResolvePositioning(float delta_time);  
  void Update(float delta_time);
  void UpdateRotation();
};

Player::Player(hgeSprite* Layer1, hgeSprite* Layer2, hgeSprite* Layer3, hgeAnimation* Layer4)
{
 Player_Sprite_Layer1 = Layer1;
 Player_Sprite_Layer2 = Layer2; 
 Player_Sprite_Layer3 = Layer3;    
 Player_Sprite_Layer4 = Layer4;         
}

//Renders the player with proper Camera offset
void Player::Render_Player()
{
 float Player_Pos_X = X_Position - Camera_X + Screen_Width/2;
 float Player_Pos_Y = Y_Position - Camera_Y + Screen_Height/2; 
 Player_Sprite_Layer4->RenderEx(Player_Pos_X, Player_Pos_Y, Angle);
 Player_Sprite_Layer3->RenderEx(Player_Pos_X, Player_Pos_Y, Angle);
 Player_Sprite_Layer2->RenderEx(Player_Pos_X, Player_Pos_Y, Angle);
 Player_Sprite_Layer1->RenderEx(Player_Pos_X, Player_Pos_Y, Angle);
}

//Instant movement of unit
void Player::UpdatePosition(float X, float Y)     {X_Position = X; Y_Position = Y;}

//Smooth movement
void Player::UpdateVelocity(float X, float Y)     {X_Velocity = X; Y_Velocity = Y;}

//Acceleration. This is going to be used the most to achieve accurate movement of units.
void Player::UpdateAcceleration(float X, float Y) {X_Acceleration = X; Y_Acceleration = Y;}
void Player::ApplyAcceleration (float X, float Y) {X_Acceleration = X_Acceleration + X; Y_Acceleration = Y_Acceleration + Y;}

//Accerlation Dampening effect to lower speed over time.
void Player::DampAcceleration(float ScaleA, float ScaleV, float Stop_threshold)              
{
 X_Acceleration = ScaleA*X_Acceleration; 
 Y_Acceleration = ScaleA*Y_Acceleration;
 X_Velocity     = ScaleV*X_Velocity;
 Y_Velocity     = ScaleV*Y_Velocity;
 if(abs(X_Velocity) < Stop_threshold) X_Velocity = 0;
 if(abs(Y_Velocity) < Stop_threshold) Y_Velocity = 0; 
}

//Updates the rotation of the player
void Player::UpdateRotation() {Angle = FaceRotation(X_Position, Y_Position, Scene2_CursorX, Scene2_CursorY);}

//We use kinematic equations here to figure out where the player's position should be.
void Player::ResolvePositioning(float delta_time) 
{
 //Equation: D = vi*t + .5*a*t^2
 X_Position = X_Position + (X_Velocity*delta_time) + (.5*X_Acceleration*delta_time*delta_time);
 Y_Position = Y_Position + (Y_Velocity*delta_time) + (.5*Y_Acceleration*delta_time*delta_time);
 //Equation: Vf = Vi + a*t
 X_Velocity = X_Velocity + X_Acceleration*delta_time;
 Y_Velocity = Y_Velocity + Y_Acceleration*delta_time;
}

void Player::Update(float delta_time)
{
 //Update footstep animation
 if(abs(X_Velocity) < 1 && abs(Y_Velocity) < 1)
  {                          
      Player_Sprite_Layer4 -> Stop();                                                      
  }
 else
  {
   Player_Sprite_Layer4->Update(delta_time);
   Player_Sprite_Layer4->Resume();
  }
/*
  if(Player[0].GetSpeedY() > -.1 && Player[0].GetSpeedY() < .1 && Player[0].GetSpeedX() > -.1 && Player[0].GetSpeedX() < .1)
    {                          
      Animation_Player_Walk -> Stop();                                                      
    }
  //This can be expanded upon later to include forward and backwards movement
  if(Player[0].GetSpeedY() < -.1 || Player[0].GetSpeedY() > .1 || Player[0].GetSpeedX() < -.1 || Player[0].GetSpeedX() > .1) 
    {
      Animation_Player_Walk -> Update(TimeStep*2);
      Animation_Player_Walk -> Resume();
    }
*/
 
}

#endif
